/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Mapper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author Nicolás Loaiza Cardona (nicoloaiza@gmail.com)
 */
public class Mapper<T> {
    
    public Mapper()
    {}
    
    
    /**
    * Constructor
    * @param  type  Class to be analized for 
    * @param  methodname  method's name
    * @return  method's parameters
    */          
    private Class[] GetParameter(Class type, String methodname)
    {
        Method[] methods = type.getMethods();  
        Method method = null;
        for(Method met : methods)
        {
            if(met.getName().equals(methodname))
            {
                method = met;
                break;
            }
        }
        if(method != null)
        {
            return method.getParameterTypes();
        }
        return null;
    }
    
    
    /**
    * Constructor
    * @param  type  Class to be analized 
    * @param  methodname  method's name
    * @return  Method with their parameters ans values
    */          
    private Object[] GetMethod(Class type,String value, String methodname)
    {
        Method[] methods = type.getMethods();  
        Method method = null;
        for(Method met : methods)
        {
            if(met.getName().equals(methodname))
            {
                method = met;
            }
        }
        if(method != null)
        {
            Class[] parameters = method.getParameterTypes();
            Class parameter = parameters[0];
            if(parameter.getName().equals("int"))
            {
                Object oParams1[] = new Object[1];
                oParams1[0] =  Integer.parseInt(value);
                return oParams1;
            }
            if(parameter.getName().equals("float"))
            {
                Object oParams1[] = new Object[1];
                oParams1[0] =  Float.parseFloat(value);
                return oParams1;
            }
            if(parameter.getName().equals("java.lang.String"))
            {
                Object oParams1[] = new Object[1];
                oParams1[0] =  value;
                return oParams1;
            }   
        }
        
        return null;
    }
       
    
    /**
    * Constructor
    * @param  maps  HashMap ArrayList with the pairs data- field
    * @param  type Class to be loaded with the data 
    * @return  ArrayList<T>  with the Objects T loaded with the data
    */          
    public ArrayList<T> Map(ArrayList<HashMap> maps,Class type)
    {
        ArrayList<T> objects = new ArrayList<T>(); 
        Iterator it;
        for(HashMap map : maps)
        {
            if(map != null)
            {
                try {
                    if(map.entrySet() != null)
                    {
                        if(map.entrySet().iterator() != null)
                        {
                            it = map.entrySet().iterator();
                            T object = (T)type.newInstance();
                            while (it.hasNext()) 
                            {
                                Map.Entry e = (Map.Entry)it.next();
                                if(e != null)
                                {
                                    Class cArgs1[] = GetParameter(type,"set" + e.getKey().toString());
                                    Object oParams1[] = GetMethod(type,e.getValue().toString(), "set" + e.getKey().toString());
                                    //Object oParams1[] = { e.getValue()};
                                    Method mtd1;
                                    try {
                                        if(cArgs1 != null)
                                        {
                                            mtd1 = type.getMethod("set" + e.getKey(),cArgs1);
                                            if((mtd1 != null) && (oParams1 != null) && (object != null))
                                            {
                                                mtd1.invoke(object,oParams1);
                                            }
                                        }
                                    } catch (IllegalArgumentException ex) {
                                    }
                                    catch(InvocationTargetException ex2){}
                                    catch(NoSuchMethodException ex3){}
                                    catch(SecurityException ex4){}
                                }
                            }
                            objects.add(object);
                        }
                    }
                } catch (InstantiationException  ex) {
                }
                catch(IllegalAccessException ex2){}
            }
        }
        return objects;
    }
    
}
